package iit.projects.etaxi.view.bean;

import iit.projects.etaxi.model.dto.CitySCDO;
import iit.projects.etaxi.model.dto.SubCitySCDO;
import iit.projects.etaxi.model.entity.City;
import iit.projects.etaxi.model.entity.SubCity;
import iit.projects.etaxi.model.service.CityService;
import iit.projects.etaxi.model.service.ServiceLocator;
import iit.projects.etaxi.model.service.SubCityService;
import iit.projects.etaxi.util.Constants;
import iit.projects.etaxi.util.JSFUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.faces.component.UIInput;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.ext.HtmlSelectOneMenu;

public class SubcityBackingBean {
	
	final Logger log = LoggerFactory.getLogger(SubcityBackingBean.class);
	
	private String cityCode;
	
	//private SubCitySCDO subCitySCDO;
	
	private SubCity subCity;
	
	//private SubCity initialSubCity;
	
	private Set<SubCity> subcities;
	
	private boolean editMode;
	
	private String subCityCodeForDelete;
	
	private List<SelectItem> cityList;
	
	private HtmlSelectOneMenu compCitylist;
	
	private HtmlInputText compSubcityCode;
	
	private HtmlInputText compSubcityName;
	
	private CityService cityService;
	
	private SubCityService subCityService;
	
	private ServiceLocator serviceLocator;
	
	@javax.annotation.PostConstruct
	public void init(){
		cityService = serviceLocator.getCityService();
		subCityService = serviceLocator.getSubCityService();
		
		loadCityList();
		//subCitySCDO = new SubCitySCDO();
		subCity = new SubCity();
	//	initialSubCity = new SubCity();
	}
	
	private void loadCityList(){
		List<City> cities = null;
		try{
			//Find all Cities.
			cities = cityService.findCities(new CitySCDO());
		}catch(Throwable e){
			return;
		}
		
		if(cities != null && !cities.isEmpty()){
			cityList = new ArrayList<SelectItem>();
			cityList.add(new SelectItem(Constants.SELECT_VALUE, Constants.SELECT_LABEL));
			
			for(City city : cities){
				cityList.add(new SelectItem(city.getCode(), city.getName()));
			}
		}
	}
	
	public void searchSubCities(ActionEvent event){
		SubCitySCDO subCitySCDO = new SubCitySCDO();
		subCitySCDO.setCityCode(this.cityCode);
		subCitySCDO.setSubCityCode(this.subCity.getCode());
		subCitySCDO.setSubCityName(this.subCity.getName());
		
		this.subcities = subCityService.findSubCities(subCitySCDO);
		
		if(this.subcities == null || this.subcities.isEmpty()){
			JSFUtils.addFacesInfoMessage("data.notfound");
			return;
		}
		
	}
	
	public void saveSubCity(ActionEvent event){
		
		if(!valid()){
			return;
		}
		try {
			if(!editMode){
				SubCity subCity = subCityService.saveSubCity(this.cityCode, this.subCity);
				
				if(subcities == null){
					subcities = new HashSet<SubCity>();
				}
				subcities.add(subCity);
			}
			else{
				SubCity subCity = subCityService.updateSubCity(this.cityCode, this.subCity);
				
				//For version controlling.
				subcities.remove(subCity);
				subcities.add(subCity);
			}
			
			JSFUtils.addFacesInfoMessage("subcity.save.successfull");
			clear(event);
		} catch (Throwable e) {
			//this.subCity = new SubCity(this.initialSubCity);
			clear(event);
			return;
		}
	}

	public void clear(ActionEvent event){
		this.editMode = false;
		this.subCity = new SubCity();
		
		compSubcityCode.resetValue();
		compSubcityName.resetValue();
	}
	
	public void valueChangeCity(ValueChangeEvent event){
		
		String cityCode = (String)event.getNewValue();
		if(cityCode != null){
			try {
				City city = cityService.findByPrimaryKey(cityCode);
				this.subcities = city.getSubcities();
				
			} catch (Throwable e) {
				return;
			}
		}
		else{
			subcities = null;
		}
	}
	
	public void loadSubCity(ActionEvent event){
		String subcityCode = (String)JSFUtils.getRequestParameter("subCityCode");
		if(subcityCode != null){
			
			if(log.isDebugEnabled()){
				log.debug("Found sub city of code " + subcityCode);
			}
			
			for(SubCity subCity : this.subcities){
				if(subCity.getCode().equals(subcityCode)){
//					this.subCitySCDO.setSubCityCode(subCity.getCode());
//					this.subCitySCDO.setSubCityName(subCity.getName());
					
					this.subCity = new SubCity(subCity);
					//this.initialSubCity = subCity;
					
					compSubcityCode.resetValue();
					compSubcityName.resetValue();
					break;
				}
			}
		}
		this.editMode = true;
	}
	
	private boolean valid(){
		boolean valid = true;
		
		if(this.subCity.getCode() == null || this.subCity.getCode().isEmpty()){
			JSFUtils.addFacesErrorMessage(compSubcityCode, UIInput.REQUIRED_MESSAGE_ID);
			valid = false;
		}
		
		if(this.subCity.getName() == null || this.subCity.getName().isEmpty()){
			JSFUtils.addFacesErrorMessage(compSubcityName, UIInput.REQUIRED_MESSAGE_ID);
			valid = false;
		}
		
		return valid;
	}
	
	public void confirmDelete(ActionEvent event){
		ConfirmationPopupBackingBean confirmBean = 
			(ConfirmationPopupBackingBean)JSFUtils.getManagedBeanValue("confirmationPopup");
		confirmBean.setMessage(JSFUtils.getResourcesProperty("delete.subcity.confirmation"));
		confirmBean.setBackingBeanAlias("subcityBean");
		confirmBean.setMethodName("deleteSubcity");
		confirmBean.setShowPopup(true);
		
		subCityCodeForDelete = (String)JSFUtils.getRequestParameter("subCityCode");
	}
	
	public void deleteSubcity(ActionEvent event){
		
		for(SubCity subCity : subcities){
			if(subCity.getCode().equals(subCityCodeForDelete)){
				try {
					subCityService.deleteSubCity(subCity);
					this.subcities.remove(subCity);
					break;
				} catch (Throwable e) {
					return;
				}
			}
		}
	}
	
	public void setServiceLocator(ServiceLocator serviceLocator) {
		this.serviceLocator = serviceLocator;
	}

	public List<SelectItem> getCityList() {
		return cityList;
	}

	public void setCityList(List<SelectItem> cityList) {
		this.cityList = cityList;
	}

	public String getCityCode() {
		return cityCode;
	}

	public void setCityCode(String cityCode) {
		this.cityCode = cityCode;
	}

	public Set<SubCity> getSubcities() {
		return subcities;
	}

	public HtmlSelectOneMenu getCompCitylist() {
		return compCitylist;
	}

	public void setCompCitylist(HtmlSelectOneMenu compCitylist) {
		this.compCitylist = compCitylist;
	}

//	public SubCitySCDO getSubCitySCDO() {
//		return subCitySCDO;
//	}
//
//	public void setSubCitySCDO(SubCitySCDO subCitySCDO) {
//		this.subCitySCDO = subCitySCDO;
//	}

	public boolean isEditMode() {
		return editMode;
	}

	public void setEditMode(boolean editMode) {
		this.editMode = editMode;
	}

	public HtmlInputText getCompSubcityCode() {
		return compSubcityCode;
	}

	public void setCompSubcityCode(HtmlInputText compSubcityCode) {
		this.compSubcityCode = compSubcityCode;
	}

	public HtmlInputText getCompSubcityName() {
		return compSubcityName;
	}

	public void setCompSubcityName(HtmlInputText compSubcityName) {
		this.compSubcityName = compSubcityName;
	}

	public SubCity getSubCity() {
		return subCity;
	}

	public void setSubCity(SubCity subCity) {
		this.subCity = subCity;
	}

}
